﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.Reflection;
using System.IO;
using WinAS.ASHost.Utilities;

namespace WinAS.ASHost
{
    class Server
    {
        private NetTcpBinding tcp_binding;
        private string port;
   
        public Server()
        {
            init();
        }

        public void init(){
            ASConsole.print("Windows Application Server (WinAS) V1.0");
            port = WinAS.ASHost.Utilities.PropertiesReader.get("server.port");
            ASConsole.print("Binding to port [" + port + "]");
            loadBinding();
            loadServices();
            openServices();
            loadWatcher();
        }

        public void loadWatcher()
        {
            FileSystemWatcher watcher = new FileSystemWatcher();
            watcher.Path = "services";
            watcher.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite | NotifyFilters.FileName | NotifyFilters.DirectoryName;
            watcher.Filter = "*.dll";

            watcher.Created += new FileSystemEventHandler(OnChanged);

            watcher.EnableRaisingEvents = true;
            ASConsole.print("Watching : " + watcher.Path);

        }

        private void OnChanged(object source, FileSystemEventArgs e)
        {
            if (e.Name.EndsWith("Impl.dll"))
            {
               ASConsole.print("Detected : " + e.Name + " - Loading ...");
                loadService(new FileInfo("services\\" + e.Name));
            }
                
        }



        private void openServices()
        {
            //svh.Open();
        }

        private void loadServices()
        {
            DirectoryInfo di = new DirectoryInfo("services");
            FileInfo[] files = di.GetFiles("*Impl.*");

            foreach (FileInfo file in files)
            {
              
                loadService(file);
            }
        }

        public void loadService(FileInfo file)
        {
            Assembly services_ass = Assembly.LoadFrom("services\\" + file.Name);
            foreach (Type t in services_ass.GetTypes())
            {
                String implementation_name = t.Name;
                String interface_name = t.Namespace + ".I" + implementation_name.Substring(0, implementation_name.IndexOf("Service"));

                String interface_file = file.Name.Substring(0, file.Name.IndexOf("Impl")) + ".dll";
                Assembly interfaces_ass = Assembly.LoadFrom("services\\" + interface_file);
                Type inter = interfaces_ass.GetType(interface_name);

                ASConsole.print("Creating Service Host for " + interface_name +  " [" +interface_file + "]");

                ServiceHost svh = new ServiceHost(t);
                svh.AddServiceEndpoint(
                    inter,
                    tcp_binding,
                    "net.tcp://localhost:" + port);
                svh.Open();

            }
        }

        private void loadBinding()
        {
            tcp_binding = BindingConfiguration.getBinding();
        }

        public void shutdown()
        {
            //svh.Close();
        }
    }
}
